package org.zebra.mybatis.plus.util;

import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import org.apache.ibatis.plugin.Interceptor;
import org.mybatis.spring.SqlSessionTemplate;
import org.zebra.mybatis.plus.core.MapperPlus;

import java.util.ArrayList;
import java.util.List;

/**
 * MyBatisPlus 工具类
 *
 * @author zhanghongbin
 */
@SuppressWarnings("unchecked")
public final class MyBatisPlusUtil {

    private MyBatisPlusUtil() {}

    /**
     * 将拦截器添加到链中
     * 由于 MybatisPlusInterceptor 不支持添加拦截器，所以只能全量设置
     *
     * @param mybatisPlusInterceptor 链
     * @param interceptor            拦截器
     * @param index                  位置
     */
    public static void addInterceptor(
            MybatisPlusInterceptor mybatisPlusInterceptor, InnerInterceptor interceptor, int index) {
        List<InnerInterceptor> inners = new ArrayList<>(mybatisPlusInterceptor.getInterceptors());
        inners.add(index, interceptor);
        mybatisPlusInterceptor.setInterceptors(inners);
    }

    public static void addInterceptor(MybatisPlusInterceptor mybatisPlusInterceptor, InnerInterceptor interceptor) {
        List<InnerInterceptor> inners = new ArrayList<>(mybatisPlusInterceptor.getInterceptors());
        for (InnerInterceptor innerInterceptor : inners) {
            if (innerInterceptor.getClass().isAssignableFrom(interceptor.getClass())) {
                return;
            }
        }
        inners.add(interceptor);
        mybatisPlusInterceptor.setInterceptors(inners);
    }

    public static void removeInterceptor(
            MybatisPlusInterceptor mybatisPlusInterceptor, Class<? extends InnerInterceptor> interceptorClass) {
        List<InnerInterceptor> inners = new ArrayList<>(mybatisPlusInterceptor.getInterceptors());
        for (InnerInterceptor innerInterceptor : inners) {
            if (innerInterceptor.getClass().isAssignableFrom(interceptorClass)) {
                inners.remove(innerInterceptor);
                mybatisPlusInterceptor.setInterceptors(inners);
                break;
            }
        }
    }

    public static void addInterceptor(Interceptor interceptor) {
        SqlSessionTemplate sqlSessionTemplate = SpringUtil.getBean(SqlSessionTemplate.class);
        if (sqlSessionTemplate != null) {
            sqlSessionTemplate.getConfiguration().addInterceptor(interceptor);
        }
    }

    public static <T> MapperPlus<T> getMapperPlus(Class<?> mapperClass) {
        // 必须用SqlSessionTemplate ,要不然不关闭连接，会有内存泄露(只使用SqlSessionUtils)
        SqlSessionTemplate sqlSessionTemplate = SpringUtil.getBean(SqlSessionTemplate.class);
        return (MapperPlus<T>) sqlSessionTemplate.getMapper(mapperClass);
    }
}
